package com.cdqidi.smsservice.handle;

import com.cdqidi.smsservice.dto.AjaxResult;
import com.cdqidi.smsservice.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.List;
import java.util.Set;


/**
 * 自定义异常处理器
 *
 * @author ruoyi
 */
@RestControllerAdvice
@Slf4j
public class DefaultExceptionHandler {
    /**
     * 请求方式不支持
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public AjaxResult handleException(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage(), e);
        return AjaxResult.error(10002, "不支持' " + e.getMethod() + "'请求");
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public AjaxResult notFount(RuntimeException e) {
        log.error("运行时异常:", e);
        return AjaxResult.error(500, "运行时异常:" + e.getMessage());
    }

    /**
     * 处理实体字段校验不通过异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(ValidationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public AjaxResult validationError(MethodArgumentNotValidException ex) {
        if(ex instanceof  MethodArgumentNotValidException){
            BindingResult result = ex.getBindingResult();
            final List<FieldError> fieldErrors = result.getFieldErrors();
            for (FieldError error : fieldErrors) {
                return AjaxResult.filedError(error.getDefaultMessage());
            }
        }
        return AjaxResult.filedError(ex.getMessage());
    }

    /**
     * 处理实体字段校验不通过异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({ConstraintViolationException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public AjaxResult validationError(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();
        for (ConstraintViolation<?> item : violations) {
            return AjaxResult.filedError(item.getMessage());
        }
        return AjaxResult.filedError(ex.getMessage());
    }

    /**
     * 缺少字段
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public AjaxResult validationError(MissingServletRequestParameterException ex) {
        return AjaxResult.filedError("参数: " + ex.getParameterName() + "不存在");
    }

    /**
     * api异常
     */
    @ExceptionHandler(ApiException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public AjaxResult handleApiException(ApiException e) {
        return e.getResult();
    }

    /**
     * api异常
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public AjaxResult handleNoHandlerFoundException(NoHandlerFoundException e) {
        return AjaxResult.error(404, e.getMessage());
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public AjaxResult handleException(Exception e) {
        log.error("运行时异常:", e);
        return AjaxResult.error(500, e.getMessage());
    }
}